#include "jtouchdatetimeedit.h"
#include "ui_jtouchdatetimeedit.h"

#include <QTECore/qteglobal.h>
#include <QRegularExpression>
#include <QTimer>

#include <climits>

namespace QTE
{

typedef JTouchDateTimeEdit::ShowFlags  ShowFlags;

class Q_DECL_HIDDEN JTouchDateTimeEditPrivate
{
public:
	explicit JTouchDateTimeEditPrivate(JTouchDateTimeEdit *q_ptr);
	~JTouchDateTimeEditPrivate();

public:
	int monthDays(int year, int month);

public:
	JTouchDateTimeEdit *q_ptr;
	Ui::JTouchDateTimeEdit *ui;
	ShowFlags m_showFlags;
};

JTouchDateTimeEditPrivate::JTouchDateTimeEditPrivate(JTouchDateTimeEdit *q_ptr) :
	q_ptr(q_ptr), ui(new Ui::JTouchDateTimeEdit)
{
	ui->setupUi(q_ptr);
	ui->msecEdit->hide();

#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
	ui->yearEdit->setRange(1970, QDateTime::fromTime_t(UINT_MAX).date().year());
#else
	ui->yearEdit->setRange(1970, QDateTime::fromSecsSinceEpoch(LLONG_MAX).date().year());
#endif
	ui->yearEdit->setValue(1970);

	ui->monthEdit->setRange(1, 12);
	ui->monthEdit->setValue(1);

	ui->dayEdit->setRange(1, 31);
	ui->dayEdit->setValue(1);

	ui->hourEdit->setRange(0, 23);
	ui->hourEdit->setValue(8);

	ui->minEdit->setRange(0, 59);
	ui->minEdit->setValue(0);

	ui->secEdit->setRange(0, 59);
	ui->secEdit->setValue(0);

	ui->msecEdit->setRange(0, 999);
	ui->msecEdit->setValue(0);

	auto lambda = [this]()
	{
		int max = monthDays(ui->yearEdit->currentValue(), ui->monthEdit->currentValue());
		ui->dayEdit->setMaximumValue(J_SCT(qreal, max));
	};
	QObject::connect(ui->yearEdit, &JNumItemScroll::currentValueChanged, lambda);
	QObject::connect(ui->monthEdit, &JNumItemScroll::currentValueChanged, lambda);
}

JTouchDateTimeEditPrivate::~JTouchDateTimeEditPrivate()
{
	delete ui;
}

int JTouchDateTimeEditPrivate::monthDays(int year, int month)
{
	int days = -1;

	switch(month)
	{
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			days = 31;
			break;

		case 4:
		case 6:
		case 9:
		case 11:
			days = 30;
			break;

		case 2:
			if( (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 )
				days = 29; //闰年
			else
				days = 28; //平年
			break;
	}
	return days;
}

/*--------------------------------------------------------------------------------------*/

JTouchDateTimeEdit::JTouchDateTimeEdit(QWidget *parent, ShowFlags flag) :
	QFrame(parent),
	d_ptr(new JTouchDateTimeEditPrivate(this))
{
	setFrameShape(Box);
	setShowFlags(flag);

	for(auto &obj : findChildren<JNumItemScroll*>(QRegularExpression(".*Edit")))
		connect(obj, &JNumItemScroll::currentValueChanged, this, [this](){emit dateTimeChanged(datetime());});
}

JTouchDateTimeEdit::JTouchDateTimeEdit(ShowFlags flag) :
	JTouchDateTimeEdit(nullptr, flag)
{

}

JTouchDateTimeEdit::~JTouchDateTimeEdit()
{
	delete d_ptr;
}

void JTouchDateTimeEdit::setShowFlags(ShowFlags flags)
{
	d_ptr->m_showFlags = flags;

	d_ptr->ui->yearEdit->setVisible(flags & Year);
	d_ptr->ui->monthEdit->setVisible(flags & Month);
	d_ptr->ui->dayEdit->setVisible(flags & Day);
	d_ptr->ui->hourEdit->setVisible(flags & Hour);
	d_ptr->ui->minEdit->setVisible(flags & Minute);
	d_ptr->ui->secEdit->setVisible(flags & Second);
	d_ptr->ui->msecEdit->setVisible(flags & MSecond);
}

ShowFlags JTouchDateTimeEdit::setShowFlags() const
{
	return d_ptr->m_showFlags;
}

QDateTime JTouchDateTimeEdit::datetime() const
{
	return QDateTime(date(), time());
}

QDate JTouchDateTimeEdit::date() const
{
	return QDate(d_ptr->ui->yearEdit->currentValue(),
				 d_ptr->ui->monthEdit->currentValue(),
				 d_ptr->ui->dayEdit->currentValue());
}

QTime JTouchDateTimeEdit::time() const
{
	return QTime(d_ptr->ui->hourEdit->currentValue(),
				 d_ptr->ui->minEdit->currentValue(),
				 d_ptr->ui->secEdit->currentValue(),
				 d_ptr->ui->msecEdit->currentValue());
}

bool JTouchDateTimeEdit::gestureEnabled() const
{
	return d_ptr->ui->yearEdit->gestureEnabled();
}

void JTouchDateTimeEdit::setDateTime(const QDateTime &datetime)
{
	setDate(datetime.date());
	setTime(datetime.time());
}

void JTouchDateTimeEdit::setDate(const QDate &date)
{
	d_ptr->ui->yearEdit->setValue(date.year());
	d_ptr->ui->monthEdit->setValue(date.month());
	d_ptr->ui->dayEdit->setValue(date.day());
}

void JTouchDateTimeEdit::setTime(const QTime &time)
{
	d_ptr->ui->hourEdit->setValue(time.hour());
	d_ptr->ui->minEdit->setValue(time.minute());
	d_ptr->ui->secEdit->setValue(time.second());
	d_ptr->ui->msecEdit->setValue(time.msec());
}

void JTouchDateTimeEdit::setGestureEnabled(bool enable)
{
	d_ptr->ui->yearEdit->setGestureEnabled(enable);
	d_ptr->ui->monthEdit->setGestureEnabled(enable);
	d_ptr->ui->dayEdit->setGestureEnabled(enable);
	d_ptr->ui->hourEdit->setGestureEnabled(enable);
	d_ptr->ui->minEdit->setGestureEnabled(enable);
	d_ptr->ui->secEdit->setGestureEnabled(enable);
	d_ptr->ui->msecEdit->setGestureEnabled(enable);
}

} //namespace QTE
